package com.jbp.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jbp.domin.LotteryNotice;
import com.jbp.model.RoomUserWheat;
import com.jbp.model.User;
import com.jbp.redis.RedisConfigService;
import com.jbp.utils.HttpClient;
import com.jbp.utils.TLSSigAPIv2;
import com.jbp.utils.UUIDUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * 腾讯云消息服务
 */
@Service
public class TecentMsgService {

    ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);

    @Autowired
    private UserService userService;
    @Autowired
    private RoomUserWheatService roomUserWheatService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private AppConfigService appConfigService;

    public static final String identifier = "administrator";

    public static final String redisKey = "tecent:cache:users2";
    @Autowired
    private RedisConfigService redisConfigService;

    /**将用户加入redis*/
    public void addUser(Integer userId){
        addUser(userId, true);
    }
    public void addUser(Integer userId, boolean first){
        if (userId!=null) {
            ListOperations<String, Integer> list = redisTemplate.opsForList();
            if (first) {
                list.leftPush(redisKey, userId);
            } else {
                list.rightPush(redisKey, userId);
            }
        }

    }

    /**批量导入*/
    public void importUsers() {
        ListOperations<String, Integer> list = redisTemplate.opsForList();

        Integer userId = list.leftPop(redisKey);
        User user = userService.getById(userId);
        boolean result = false;
        if (user != null) {
            result = accountImport(user);
        }
        if (!result) {
            addUser(userId, false);
        }
    }

    /**获取签名*/
    public String getSign(String userId) {
        Object tecent_sdkappid = redisConfigService.get("tecent_sdkappid");
        if (tecent_sdkappid == null) {
            String sdkappidTemp = appConfigService.getV("tecent_sdkappid");
            redisConfigService.set("tecent_sdkappid", sdkappidTemp);
            tecent_sdkappid = redisConfigService.get("tecent_sdkappid");
        }
        long sdkappid = Long.parseLong(tecent_sdkappid.toString());
        Object tecent_appkey = redisConfigService.get("tecent_appkey");
        if (tecent_appkey == null) {
            String keyTemp = appConfigService.getV("tecent_appkey");
            redisConfigService.set("tecent_appkey", keyTemp);
            tecent_appkey = redisConfigService.get("tecent_appkey");
        }
//        String key = appConfigService.getV("tecent_appkey");
        String key = tecent_appkey.toString();
        return new TLSSigAPIv2(sdkappid, key).genSig(userId, 60*60*24*3);
    }

    /**导入单个用户*/
    public boolean accountImport(User user) {
        try {

            String servicename = "im_open_login_svc";
            String command = "account_import";

//            long sdkappid = Long.parseLong(propertyService.getV("tecent_sdkappid"));
//            String key = propertyService.getV("tecent_appkey");
//            String usersig = new TLSSigAPIv2(sdkappid, key).genSig(identifier, 60*5);
            String usersig = getSign(identifier);

            HashMap<String, Object> params = new HashMap<>();
            params.put("Identifier",user.getId().toString());
            params.put("Nick",user.getName());
            params.put("FaceUrl",user.getImg());

            JSONObject jsonObject = sendRequest(servicename,command,identifier, usersig, params);
            if (jsonObject!=null && "OK".equalsIgnoreCase(jsonObject.getString("ActionStatus"))
                    && 0==jsonObject.getInteger("ErrorCode")) {
//                System.out.println("用户："+user.getName()+"导入成功");
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
//        System.out.println("用户："+user.getName()+"导入失败");
        return false;
    }

    /**
     * 发送自定义单体消息
     * 管理员指定某一帐号向另一帐号发送消息，同时将消息同步到 From_Account 发送方终端
     * */
    public boolean sendMsg(String fromUserId, String toUserId, String message, String type) {
//        long sdkappid = Long.parseLong(propertyService.getV("tecent_sdkappid"));
//        String key = propertyService.getV("tecent_appkey");
//        String usersig = new TLSSigAPIv2(sdkappid, key).genSig(identifier, 60);

        String usersig = getSign(identifier);
        String servicename = "openim";
        String command = "sendmsg";

        HashMap<String, Object> contentMap = new HashMap<>();
        contentMap.put("Data", message);
        contentMap.put("Ext", type);

        HashMap<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("MsgContent", contentMap);
        bodyMap.put("MsgType", "TIMCustomElem");

        ArrayList<HashMap<String, Object>> bodys = new ArrayList<>();
        bodys.add(bodyMap);

        HashMap<String, Object> params = new HashMap<>();
        params.put("SyncOtherMachine", 1); //消息同步至发送方 1是 2否
        params.put("From_Account",fromUserId);
        params.put("To_Account",toUserId);
        params.put("MsgRandom", Integer.parseInt(UUIDUtil.getNumber(5)));
        params.put("MsgLifeTime", 604800);
        params.put("MsgTimeStamp", System.currentTimeMillis()/1000);
        params.put("MsgBody", bodys);

        JSONObject jsonObject = sendRequest(servicename,command,identifier, usersig, params);
        if (jsonObject!=null && "OK".equalsIgnoreCase(jsonObject.getString("ActionStatus"))) {
            return true;
        }
        return false;
    }

    /**
     * 发送单体消息
     * 管理员指定某一帐号向另一帐号发送消息，同时将消息同步到 From_Account 发送方终端
     * */
    public boolean sendMsg(String fromUserId, String toUserId, String message) {
        long sdkappid = Long.parseLong(appConfigService.getV("tecent_sdkappid"));
        String key = appConfigService.getV("tecent_appkey");
        String servicename = "openim";
        String command = "sendmsg";

        String usersig = new TLSSigAPIv2(sdkappid, key).genSig(identifier, 60);

        HashMap<String, Object> contentMap = new HashMap<>();
        contentMap.put("Text", message);

        HashMap<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("MsgContent", contentMap);
        bodyMap.put("MsgType", "TIMTextElem");

        ArrayList<HashMap<String, Object>> bodys = new ArrayList<>();
        bodys.add(bodyMap);

        HashMap<String, Object> params = new HashMap<>();
        params.put("SyncOtherMachine", 1); //消息同步至发送方 1是 2否
        params.put("From_Account",fromUserId);
        params.put("To_Account",toUserId);
        params.put("MsgRandom", Integer.parseInt(UUIDUtil.getNumber(5)));
        params.put("MsgLifeTime", 604800);
        params.put("MsgTimeStamp", System.currentTimeMillis()/1000);
        params.put("MsgBody", bodys);

        JSONObject jsonObject = sendRequest(servicename,command,identifier, usersig, params);
        if (jsonObject!=null && "OK".equalsIgnoreCase(jsonObject.getString("ActionStatus"))) {
            return true;
        }
        return false;
    }

    /**发送全局广播
     * */
    public void sendOnlineBroadCast(String message, Integer roomId, String account) {
        QueryWrapper<RoomUserWheat> queryWrapper = new QueryWrapper<>();
        if (roomId!=null) {
            queryWrapper.eq("room_id", roomId);
        }
        if (account==null) {
            account = identifier;
        }
        //查询所有在房用户
        List<String> userIds = roomUserWheatService.list(queryWrapper).stream()
                .map(RoomUserWheat::getUserId).distinct().map(id -> id.toString()).collect(Collectors.toList());
//        System.out.println(Arrays.toString(userIds.toArray()));
        //最多支撑500人
        if (userIds!=null && userIds.size()>0) {
            for (int i=0; i<userIds.size(); i=i+500) {
                int end = Math.min(i+500, userIds.size());
                sendMsgsFromManger(userIds.subList(i,end), message, account);
                /*int finalI = i;
                String finalAccount = account;
                executor.submit(() -> {
                    sendMsgsFromManger(userIds.subList(finalI,end), message, finalAccount);
                });*/
            }
//            userIds.forEach(userId->{
//                sendMsgFromManger(userId, message);
//            });
        }
    }

    /**
     * 管理员向其他用户批量发消息
     * */
    public boolean sendMsgsFromManger(List<String> toUserIds, String message, String account) {
//        System.out.println(Arrays.toString(toUserIds.toArray()));
        String servicename = "openim";
        String command = "batchsendmsg";
//        long sdkappid = Long.parseLong(propertyService.getV("tecent_sdkappid"));
//        String key = propertyService.getV("tecent_appkey");
//        String usersig = new TLSSigAPIv2(sdkappid, key).genSig(account, 60);
        String usersig = getSign(account);

        HashMap<String, Object> contentMap = new HashMap<>();
        contentMap.put("Text", message);

        HashMap<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("MsgContent", contentMap);
        bodyMap.put("MsgType", "TIMTextElem");

        HashMap<String, Object> params = new HashMap<>();
        params.put("SyncOtherMachine", 2); //消息同步至发送方
        params.put("To_Account",toUserIds);
        params.put("MsgRandom", Integer.parseInt(UUIDUtil.getNumber(5)));
        params.put("MsgLifeTime", 0); //单位 秒  如果为0 只发在线用户 并且不保存离线及漫游
        params.put("MsgTimeStamp", System.currentTimeMillis()/1000);
        params.put("MsgBody", new Object[]{bodyMap});

        JSONObject jsonObject = sendRequest(servicename,command, account, usersig, params);
        if (jsonObject!=null && "OK".equalsIgnoreCase(jsonObject.getString("ActionStatus"))) {
            return true;
        }
        return false;
    }

    /**
     * 管理员向其他用户发消息
     * */
    public boolean sendMsgFromManger(String account, String toUserId, String message) {
        String servicename = "openim";
        String command = "sendmsg";
//        long sdkappid = Long.parseLong(propertyService.getV("tecent_sdkappid"));
//        String key = propertyService.getV("tecent_appkey");
//        String usersig = new TLSSigAPIv2(sdkappid, key).genSig(account, 60);
        String usersig = getSign(account);

        HashMap<String, Object> contentMap = new HashMap<>();
        contentMap.put("Text", message);

        HashMap<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("MsgContent", contentMap);
        bodyMap.put("MsgType", "TIMTextElem");

        HashMap<String, Object> params = new HashMap<>();
        params.put("SyncOtherMachine", 2); //消息同步至发送方
        params.put("To_Account",toUserId);
        params.put("MsgRandom", Integer.parseInt(UUIDUtil.getNumber(5)));
        params.put("MsgLifeTime", 60);
        params.put("MsgTimeStamp", System.currentTimeMillis()/1000);
        params.put("MsgBody", new Object[]{bodyMap});

        JSONObject jsonObject = sendRequest(servicename,command, account, usersig, params);
        if (jsonObject!=null && "OK".equalsIgnoreCase(jsonObject.getString("ActionStatus"))) {
            return true;
        }
        return false;
    }

    /**发送请求*/
    public JSONObject sendRequest(String servicename, String command, String account, String usersig, HashMap<String, Object> params) {
//        long sdkappid = Long.parseLong(appConfigService.getV("tecent_sdkappid"));
        Object tecent_sdkappid = redisConfigService.get("tecent_sdkappid");
        if (tecent_sdkappid == null) {
            String sdkappidTemp = appConfigService.getV("tecent_sdkappid");
            redisConfigService.set("tecent_sdkappid", sdkappidTemp);
            tecent_sdkappid = redisConfigService.get("tecent_sdkappid");
        }
        long sdkappid = Long.parseLong(tecent_sdkappid.toString());
        try {
            long random = System.currentTimeMillis();
            String url = "https://console.tim.qq.com/v4/"+servicename+"/"+command
                    +"?sdkappid="+sdkappid+"&identifier="+account+"&usersig="+usersig
                    +"&random="+random+"&contenttype=json";

            String json = HttpClient.doPostJson(params, null, url);
//            System.out.println(json);
            if (StringUtils.isNotEmpty(json)) {
                JSONObject jsonObject = JSON.parseObject(json);
                return jsonObject;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    //推送大奖消息
    public void sendLotteryNotice(LotteryNotice notice) {
    }
}